<template>
  <div>
    <t-modal
      :title="operate == 1 ? '上传' : '编辑'"
      width="900px"
      :visible="visible"
      @cancel="closeModal()"
      @ok="handleOk()"
      wrapClassName="upload-drawing-container"
      forceRender
      :confirmLoading="confirmLoading"
    >
      <a-form-model
        ref="ruleForm"
        :model="form"
        :rules="rules"
        :label-col="labelCol"
        :wrapper-col="wrapperCol"
      >
        <!-- 所属文件夹 -->
        <a-form-model-item
          ref="folderName"
          label="所属文件夹"
          prop="folderName"
        >
          <a-tree-select
            :disabled="operate == 2"
            v-model="form.folderName"
            show-search
            placeholder="请选择所属文件夹"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
            allow-clear
            tree-default-expand-all
            treeNodeFilterProp="title"
            :replaceFields="{
              children: 'children',
              title: 'nodeName',
              key: 'uuid',
              value: 'id',
            }"
            :tree-data="$parent.treeData"
          >
          </a-tree-select>
        </a-form-model-item>
        <!-- 图纸单位 -->
        <a-form-model-item ref="unit" label="图纸单位" prop="unit">
          <a-select v-model="form.unit" placeholder="请选择图纸单位">
            <a-select-option
              :value="item.key"
              v-for="item in form.unitSource"
              :key="item.key"
            >
              {{ item.value }}
            </a-select-option>
          </a-select>
        </a-form-model-item>
        <!-- 文件 -->
        <a-form-model-item ref="fileList" label="文件" prop="fileList">
          <a-upload
            accept=".dwg,.dxf"
            :fileList="form.fileList"
            :beforeUpload="beforeUpload"
          >
            <a-button :disabled="form.fileList.length == 1">
              <a-icon type="upload" /> 点击上传
            </a-button>
            <div class="upload-file-list-warp" @click.stop>
              <div
                class="file-item"
                v-for="(item, index) in form.fileList"
                :key="index"
              >
                <div class="icon" :class="getFileType(item.name)"></div>
                <div class="body">
                  <div class="name">
                    {{ item.name }}
                  </div>
                  <div class="size">
                    ({{
                      operate == 1 ? getFileSize(item.size) + "M" : item.size
                    }})
                  </div>
                </div>
                <div class="operate">
                  <!-- <a-icon type="eye" class="preview-btn" /> -->
                  <a-icon type="loading" v-if="uploadStatus == 0" />
                  <a-icon
                    v-else
                    type="delete"
                    class="delete-btn"
                    @click="deleteChooseFile(index)"
                  />
                </div>
              </div>
            </div>
          </a-upload>
        </a-form-model-item>
      </a-form-model>
    </t-modal>
  </div>
</template>
<script>
import { axios } from "@/utils/request";
import { resolve } from "@antv/x6/lib/registry/router/manhattan/options";
export default {
  name: "uploadModal",
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    operate: {
      type: Number,
      default: 1,
    },
  },
  data() {
    return {
      labelCol: { span: 4 },
      wrapperCol: { span: 18 },
      form: {
        //文件名称
        folderName: undefined,
        //图纸单位
        unit: undefined,
        unitSource: [
          { key: "CAD_UNIT_Kilometer", value: "千米" },
          { key: "CAD_UNIT_Hectometer", value: "百米" },
          { key: "CAD_UNIT_Decameter", value: "十米" },
          { key: "CAD_UNIT_Meter", value: "米" },
          { key: "CAD_UNIT_Decimeter", value: "分米" },
          { key: "CAD_UNIT_Centimeter", value: "厘米" },
          { key: "CAD_UNIT_Millimeter", value: "毫米" },
          { key: "CAD_UNIT_Micron", value: "微米" },
          { key: "CAD_UNIT_Nanometer", value: "纳米" },
          { key: "CAD_UNIT_Mile", value: "英里" },
          { key: "CAD_UNIT_Inch", value: "英寸" },
          { key: "CAD_UNIT_Microinch", value: "微英寸" },
          { key: "CAD_UNIT_Mil", value: "毫英寸" },
          { key: "CAD_UNIT_Foot", value: "英尺" },
          { key: "CAD_UNIT_Yard", value: "码" },
          { key: "CAD_UNIT_Angstrom", value: "埃" },
          { key: "CAD_UNIT_Gigameter", value: "百万公里" },
          { key: "CAD_UNIT_Astro", value: "天文" },
          { key: "CAD_UNIT_Lightyear", value: "光年" },
          { key: "CAD_UNIT_Parsec", value: "天体" },
        ],
        //文件
        fileList: [],
      },
      rules: {
        folderName: [
          {
            required: true,
            message: "请选择所属文件夹",
            trigger: "change",
          },
        ],
        unit: [
          {
            required: true,
            message: "请选择图纸单位",
            trigger: "change",
          },
        ],
        fileList: [
          {
            required: true,
            message: "请选择文件",
            trigger: "change",
          },
        ],
      },
      uploadStatus: 0,
      uploadFileSource: {},
      confirmLoading: false,
    };
  },
  watch: {
    visible: {
      handler(val) {
        if (val) {
          let { operate } = this;
          switch (operate) {
            //新增
            case 1:
              this.form.fileList = [];
              break;

            //编辑
            case 2:
              let { currentTreeNode, uploadModal } = this.$parent;
              let { id } = currentTreeNode;
              let { row } = uploadModal;
              let { fileInfo, unit } = row;
              this.uploadStatus = 1;
              this.form.folderName = id;
              this.form.unit = unit ?? undefined;
              if (fileInfo) {
                let { fileName, fileSize, uuid } = fileInfo;
                this.form.fileList = [
                  {
                    uid: uuid,
                    name: fileName,
                    status: "done",
                    size: fileSize,
                    url: "",
                  },
                ];
              }
              break;

            default:
              break;
          }
        }
      },
    },
  },
  mounted() {},
  methods: {
    //上传文件前置监听
    beforeUpload(file, fileList) {
      let { name } = file;
      if (this.form.fileList.some((v) => v.name == name)) {
        this.$message.warning(`文件：【${name}】已存在！`);
        return false;
      }
      this.uploadStatus = 0;
      this.handleUploadFile(file);
      this.form.fileList.push(file);
      return false;
    },

    //
    async cutFile(file) {
      let CHUNK_SIZE = 1024 * 1024 * 20;
      let chunkCount = Math.ceil(file.size / CHUNK_SIZE);
      let result = [];
      for (let i = 0; i < chunkCount; i++) {
        let chunk = await this.createChunk(file, i, CHUNK_SIZE);
        result.push(chunk);
      }
      return result;
    },

    createChunk(file, index, chunkSize) {
      return new Promise((resolve) => {
        let start = index * chunkSize;
        let end = start + chunkSize;
        let blob = file.slice(start, end);
        resolve(blob);
      });
    },

    //上传文件
    handleUploadFile(file) {
      let formData = new FormData();
      formData.append("bucket", "yx-cloud-vue");
      formData.append("file", file);
      axios
        .post(`/document/minio/uploadfile`, formData, {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        })
        .then((res) => {
          let { statusCode } = res;
          if (statusCode == 200) {
            this.uploadStatus = 1;
            this.uploadFileSource = res;
          } else {
            this.uploadFileSource = {};
            this.form.fileList = [];
            this.$message.error("文件上传失败，请稍后重试~");
          }
        })
        .catch((_) => {
          this.$message.error("文件失败，请重试！");
          this.form.fileList = [];
          this.uploadFileSource = {};
        })
        .finally((_) => {});
    },

    //删除已经选择的文件
    deleteChooseFile(index = 0) {
      this.form.fileList = this.form.fileList.filter((v, i) => i != index);
    },

    //确定
    handleOk() {
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          let { operate } = this;
          switch (operate) {
            //新增上传
            case 1:
              this.handleAdd();
              break;

            //编辑上传
            case 2:
              let file = this.form.fileList?.[0] ?? "";
              if (file instanceof File) {
                this.handleEdit();
              } else {
                this.handleEdit(1);
              }
              break;

            default:
              break;
          }
        } else {
          this.showResult = false;
          return false;
        }
      });
    },

    //新增上传
    handleAdd() {
      let { uploadStatus } = this;
      let { folderName, unit } = this.form;
      let { dfsFileUuid } = this.uploadFileSource;
      if (uploadStatus == 0) {
        this.$message.warning("文件上传中，请等待~");
        return;
      }
      this.confirmLoading = true;
      axios
        .post(
          `/probusiness/bimCadFile/save`,
          {
            classifyId: folderName,
            dfsFileUuid,
            unit,
          },
          {
            headers: {
              "Content-Type": "application/json",
            },
          }
        )
        .then((res) => {
          let { data } = res;
          let { statusCode, message } = res;
          if (statusCode == 200 && message == "success") {
            this.uploadBlackHole(data);
          } else {
            this.confirmLoading = false;
            this.$message.error("上传失败，请稍后重试！");
          }
        })
        .catch((_) => {
          this.confirmLoading = false;
          this.$message.error("上传失败，请稍后重试！");
        })
        .finally((_) => {});
    },

    //编辑上传
    handleEdit(type) {
      let { uploadStatus } = this;
      let { folderName, unit } = this.form;
      let { dfsFileUuid } = this.uploadFileSource;
      let { uploadModal } = this.$parent;
      let { row } = uploadModal;
      let { uuid } = row;
      this.confirmLoading = true;
      if (uploadStatus == 0) {
        this.$message.warning("文件上传中，请等待~");
        return;
      }
      axios
        .post(
          `/probusiness/bimCadFile/updateData`,
          {
            classifyId: folderName,
            dfsFileUuid,
            uuid,
            unit,
          },
          {
            headers: {
              "Content-Type": "application/json",
            },
          }
        )
        .then((res) => {
          let { data } = res;
          let { statusCode, message } = res;
          if (statusCode == 200 && message == "success") {
            if (!type) {
              this.uploadBlackHole(data);
            } else {
              let { id } = this.$parent.currentTreeNode;
              if (id == this.form.folderName) {
                this.$parent.handleSearch();
              }
              this.closeModal();
            }
          } else {
            this.confirmLoading = false;
            this.$message.error(message ?? "编辑失败，请稍后重试！");
          }
        })
        .catch((_) => {
          this.confirmLoading = false;
          this.$message.error(message ?? "编辑失败，请稍后重试！");
        })
        .finally((_) => {
          if (type) {
            this.confirmLoading = false;
          }
        });
    },

    //同步上传到黑洞
    async uploadBlackHole(uuid = "") {
      let { fileList } = this.form;
      let { operate } = this;
      let file = fileList?.[0] ?? "";
      let chunks = await this.cutFile(file);
      let formData = new FormData();
      formData.append("uploadFile", file);
      axios
        .post(`/probusiness/bimCadFile/uploadCadFile?uuid=${uuid}`, formData, {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        })
        .then((res) => {
          let { statusCode, message, data } = res;
          if (statusCode == 200) {
            let { id } = this.$parent.currentTreeNode;
            let proms = [];
            if (data?.FileId) {
              chunks.forEach(async (file, i) => {
                proms.push(() => this.bigFileUpload(file, i, data));
              });
              // 使用Array.reduce()来串联这些Promise
              const promiseChain = proms.reduce(
                (previousPromise, currentFunction) => {
                  return previousPromise.then((result) => {
                    return currentFunction();
                  });
                },
                Promise.resolve()
              );
              promiseChain
                .then((result) => {
                  let { statusCode, message } = result;
                  if (statusCode == 200) {
                    this.$message.success(
                      `${operate == 1 ? "上传" : "编辑"}成功！`
                    );
                    this.closeModal();
                    if (id == this.form.folderName) {
                      this.$parent.handleSearch();
                    }
                  } else {
                    this.$message.error(
                      message ??
                        `${operate == 1 ? "上传" : "编辑"}失败，请稍后重试！`
                    );
                  }
                })
                .catch((error) => {
                  this.$message.error(
                    `${operate == 1 ? "上传" : "编辑"}失败，请稍后重试！`
                  );
                })
                .finally((_) => {
                  this.confirmLoading = false;
                });
            } else {
              this.$message.success(`${operate == 1 ? "上传" : "编辑"}成功！`);
              if (id == this.form.folderName) {
                this.$parent.handleSearch();
              }
              this.closeModal();
              this.confirmLoading = false;
            }
          } else {
            this.$message.error(
              message ?? `${operate == 1 ? "上传" : "编辑"}失败，请稍后重试！`
            );
            this.closeModal();
            this.confirmLoading = false;
          }
        })
        .catch((_) => {
          this.confirmLoading = false;
          this.$message.error(
            `${operate == 1 ? "上传" : "编辑"}失败，请稍后重试！`
          );
        })
        .finally((_) => {});
    },

    //大文件上传接口
    bigFileUpload(file, i, data) {
      let { FileDatald, FileId, Key } = data;
      let formData = new FormData();
      formData.append("FileId", FileId);
      formData.append("FileInfo", file);
      formData.append("FileDataId", FileDatald);
      formData.append("Key", Key);
      formData.append("BlobIndex", i);
      return new Promise((resolve, reject) => {
        console.log({ FileDatald, FileId, Key, i, file });
        axios
          .post(`/probusiness/bimCadFile/project/cadFile/append`, formData, {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          })
          .then((res) => {
            let {} = res;
            resolve(res);
          })
          .catch((_) => {
            reject();
          });
      });
    },

    //计算文件大小
    getFileSize(size = 0) {
      if (size) {
        return (size / 1024 / 1024).toFixed(2);
      }
      return 0;
    },

    //文件类型
    getFileType(name = "") {
      if (name) {
        let type = name.split(".")?.[1] ?? "";
        return type.toLowerCase() == "pdf" ? "pdf" : "cad";
      }
      return "";
    },

    //关闭
    closeModal() {
      setTimeout((_) => {
        this.form.folderName = "";
        this.form.unit = undefined;
        this.form.fileList = [];
        this.uploadFileSource = {};
        this.$refs?.ruleForm?.resetFields();
      }, 500);
      this.$emit("update:visible", false);
    },
  },
};
</script>
<style lang="less" scoped>
/deep/.upload-drawing-container {
  .upload-file-list-warp {
    padding-top: 10px;
    .file-item {
      width: 652px;
      height: 32px;
      background: #f2f2f2;
      border-radius: 4px;
      display: flex;
      align-items: center;
      padding: 0 8px;
      &:not(:last-child) {
        margin-bottom: 10px;
      }
      .icon {
        width: 18px;
        height: 18px;
        background: url("./images/cad.png");
        background-size: 100% 100%;
        margin-right: 8px;
        flex-shrink: 0;
        &.pdf {
          background: url("./images/pdf.png");
          background-size: 100% 100%;
        }
      }
      .body {
        display: flex;
        flex: 1;
        overflow: hidden;
        .name {
          max-width: 460px;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }
        .size {
          color: #bfbfbf;
          font-size: 14px;
          margin-left: 20px;
        }
      }
      .operate {
        .preview-btn {
          color: #1677ff;
          margin-right: 12px;
          cursor: pointer;
        }
        .delete-btn {
          cursor: pointer;
          color: #ff2d2d;
        }
      }
    }
  }
  .ant-upload-list {
    display: none;
  }
}
</style>
